import { _decorator, Component, Node, director, game, view, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('GameManager')
export class GameManager extends Component {
    // Singleton pattern
    private static _instance: GameManager = null;
    public static get instance(): GameManager {
        return this._instance;
    }

    @property({ type: Node })
    private player: Node = null;

    @property
    private gameTime: number = 0;

    @property
    private isPaused: boolean = false;

    @property
    private score: number = 0;

    @property
    private level: number = 1;

    @property
    private experience: number = 0;

    @property
    private experienceToNextLevel: number = 100;

    // Game states
    public isGameOver: boolean = false;
    public isGameStarted: boolean = false;

    onLoad() {
        // Establish singleton
        if (GameManager._instance === null) {
            GameManager._instance = this;
            game.addPersistRootNode(this.node);
        } else {
            this.node.destroy();
            return;
        }
    }

    start() {
        this.initGame();
    }

    update(deltaTime: number) {
        if (!this.isGameStarted || this.isPaused || this.isGameOver) return;

        this.gameTime += deltaTime;
    }

    private initGame() {
        this.gameTime = 0;
        this.score = 0;
        this.level = 1;
        this.experience = 0;
        this.experienceToNextLevel = 100;
        this.isGameOver = false;
        this.isPaused = false;
    }

    public startGame() {
        this.isGameStarted = true;
    }

    public pauseGame() {
        this.isPaused = true;
    }

    public resumeGame() {
        this.isPaused = false;
    }

    public gameOver() {
        this.isGameOver = true;
    }

    public addScore(value: number) {
        this.score += value;
    }

    public addExperience(value: number) {
        this.experience += value;
        if (this.experience >= this.experienceToNextLevel) {
            this.levelUp();
        }
    }

    private levelUp() {
        this.level++;
        this.experience -= this.experienceToNextLevel;
        this.experienceToNextLevel = Math.floor(this.experienceToNextLevel * 1.2);
        // TODO: Trigger level up event for UI and player upgrades
    }

    public getGameTime(): number {
        return this.gameTime;
    }

    public getScore(): number {
        return this.score;
    }

    public getLevel(): number {
        return this.level;
    }

    public getExperience(): number {
        return this.experience;
    }

    public getExperienceToNextLevel(): number {
        return this.experienceToNextLevel;
    }

    public getPlayer(): Node {
        return this.player;
    }

    public resetGame() {
        director.loadScene(director.getScene().name);
    }
}


